
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Resources;
using System.Text;
using System.Xml;
using System.Xml.Schema;


namespace MVCFramework
{
    public class XmlControllerConfigurator
    {
        private const string RootNode = "MvcFrameorkModels";
        public static void Configure( IModel model,Assembly assembly,Type type, string resourceName)
        {
            ParseResourceAssembly(model,assembly, type, resourceName);
        }
        private static void ParseResourceAssembly(IModel model, Assembly assembly, Type type, string resourceName)
        {
            Stream xmlStream = null;
            try
            {
                if (type == null)
                    xmlStream = assembly.GetManifestResourceStream(resourceName);
                else
                    xmlStream = assembly.GetManifestResourceStream(type, resourceName);
                String[] info = assembly.GetManifestResourceNames();
                ManifestResourceInfo infom = assembly.GetManifestResourceInfo("MVCFramework.XmlControllersConfigurator.xml");
                if (xmlStream == null)
                {
                    xmlStream = assembly.GetManifestResourceStream("MVCFramework.XmlControllersConfigurator.xml");
                }

                XmlDocument document = new XmlDocument();
                document.PreserveWhitespace = true;
                document.Load(xmlStream);
                XmlNode modelCongfigurationNode = document.SelectSingleNode(RootNode);

                if (modelCongfigurationNode == null)
                {

                }
                XmControllerlParser.Parse(model, modelCongfigurationNode);
            }
            catch { throw new Exception ("Controllers Configuration Failled to Initialize"); }
            finally
            {
                if (xmlStream != null)
                {
                    xmlStream.Close();
                }
            }
        }
    }

    internal static class XmControllerlParser
    {
        private const string IdAttribute = "id";
        private const string EnabledAttribute = "enabled";
        private const string TypeAttribute = "type";
        private const string EnumerationAttribute = "enumeration";
        private const string StartingViewAttribute = "startingView";
        private const string ViewManagerAttribute = "viewManager";
        private const string ControllerAttribute = "controller";

        public static void Parse(IModel model,XmlNode xml)
        {
            Debug.Assert(xml != null);
            XmlNodeList typeNodes = xml.SelectNodes("//*[@type]");
            ParseControllers(model,xml);
        }

        private static void ParseControllers(  IModel model ,  XmlNode xml)
        {
            if (! (model is Models.ControllersFilterModelDecorator )) return;

            XmlNodeList nodelist = xml.SelectNodes("ModelConfiguration");

            foreach (XmlNode node in nodelist)
                if (node.Attributes[IdAttribute].Value == model.Id)
                    xml =  node;

            XmlNode controllersNode = xml.SelectSingleNode("controllers");

            if (controllersNode == null) throw new Exception("Configuration File dose not decler controllers section for this model");

            IDictionary<string, MVCFramework.Models.Controllers.Controller> _ControllerLookUp = new Dictionary<string , MVCFramework.Models.Controllers.Controller>();


            if (controllersNode != null)
            {
                XmlAttribute enumerationAttribute = controllersNode.Attributes[EnumerationAttribute];
                XmlNodeList nodeList = controllersNode.SelectNodes("controller");

                List<MVCFramework.Models.Controllers.IController> _controllers = new List<MVCFramework.Models.Controllers.IController>();

                _ControllerLookUp.Add(((Models.ControllersFilterModelDecorator)model).basecontroller.id.ToString(), ((Models.ControllersFilterModelDecorator)model).basecontroller);

                foreach (XmlNode node in nodeList)
                {
                    XmlAttribute idAttribute = node.Attributes[IdAttribute];
                    XmlAttribute typeAttribute = node.Attributes[TypeAttribute];
                    string Controllertype = typeAttribute.Value  ;

                    Type type = Type.GetType(Controllertype);

                    object op = BuildingBasicDomain . DefaultFactoryBase.CreateInstance(type ,
             new Type[] { typeof(IModel) }, new object[] { model }, new string[] {"model"});

                    MVCFramework.Models.Controllers.Controller _curController =  ((MVCFramework.Models.Controllers.Controller)op);

                    _curController.id = idAttribute.Value;
                    _controllers.Add(_curController);
                    _ControllerLookUp.Add(_curController.id.ToString (), _curController);

                    # region enable controller 

                    XmlAttribute enabledAttribute = node.Attributes[EnabledAttribute];
                    bool isEnabled = bool.Parse(enabledAttribute.Value);
                    _curController.IsEnabled = isEnabled;  

                    #endregion

                }

                foreach (XmlNode node in nodeList)
                {
                    XmlNodeList Associeted = node.SelectNodes("NextAddition");
                    XmlNode nodecontr = null ;

                    if (Associeted.Count > 0)
                        nodecontr = Associeted[0];

                    XmlAttribute idaddAttribute = nodecontr.Attributes[IdAttribute];

                    MVCFramework.Models.Controllers.Controller _controllerNext = _ControllerLookUp[idaddAttribute.Value];
                    MVCFramework.Models.Controllers.Controller _controllerToset = _ControllerLookUp[node.Attributes[IdAttribute].Value];

                  _controllerToset.NextAdditionController = _controllerNext;

                  Associeted = node.SelectNodes("NextRemoval");

                  nodecontr = null;
                  if (Associeted.Count > 0)
                      nodecontr = Associeted[0];

                  idaddAttribute = nodecontr.Attributes[IdAttribute];

                  MVCFramework.Models.Controllers.Controller _controllerNextRemove = _ControllerLookUp[idaddAttribute.Value];
                  _controllerToset.NextRemovalController = _controllerNextRemove;

                }

          //   XmlNode AdditioncontrollersNode = nodeList . SelectSingleNode("AdditionController");
                XmlNode AdditioncontrollersNode = controllersNode.SelectSingleNode("AdditionController");
            XmlAttribute newidaddAttribute = AdditioncontrollersNode.Attributes[IdAttribute];

            ((Models.ControllersFilterModelDecorator)model).AdditionController = _ControllerLookUp[newidaddAttribute.Value];



         //   XmlNode RemovalcontrollersNode = nodeList.SelectSingleNode("AdditionController");
            XmlNode RemovalcontrollersNode = controllersNode.SelectSingleNode("RemovalController");
            newidaddAttribute = RemovalcontrollersNode.Attributes[IdAttribute];

            ((Models.ControllersFilterModelDecorator)model).RemovalController = _ControllerLookUp[newidaddAttribute.Value];
            }



        }
    }



}
